#include "adc.h"

// 初始化
void ADC1_Init(void)
{
    // 1. 时钟配置
    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
    // CFGR：ADCPRE - 10，6分频，得到 12MHz
    RCC->CFGR |= RCC_CFGR_ADCPRE_1;
    RCC->CFGR &= ~RCC_CFGR_ADCPRE_0;

    // 2. GPIO工作模式，PC0，模拟输入，00 00
    GPIOC->CRL &= ~GPIO_CRL_MODE0;
    GPIOC->CRL &= ~GPIO_CRL_CNF0;

    // 3. ADC配置
    // 3.1 工作模式：禁用扫描模式
    ADC1->CR1 &= ~ADC_CR1_SCAN;

    // 3.2 启用连续转换模式(单曲循环)、
    ADC1->CR2 |= ADC_CR2_CONT;

    // 3.3 数据右对齐（默认）
    ADC1->CR2 &= ~ADC_CR2_ALIGN;

    // 3.4 设置通道10的采样时间，001 - 7.5个时钟周期
    ADC1->SMPR1 &= ~ADC_SMPR1_SMP10;
    ADC1->SMPR1 |= ADC_SMPR1_SMP10_0;

    // 3.5 规则组通道序列配置
    // 3.5.1 规则组中的通道个数 L
    ADC1->SQR1 &= ~ADC_SQR1_L;

    // 3.5.2 将通道号 10 保存到序列中的第一位
    ADC1->SQR3 &= ~ADC_SQR3_SQ1;
    ADC1->SQR3 |= 10 << 0;

    // 3.5 选择软件触发AD转换
    // ADC1->CR2 |= ADC_CR2_EXTTRIG;
    // ADC1->CR2 |= ADC_CR2_EXTSEL;    // 选择的就是SWSTART控制AD转换
}

// 开启转换
void ADC1_StartConvert(void)
{
    // 1. 上电唤醒
    ADC1->CR2 |= ADC_CR2_ADON;

    // 2. 执行校准
    ADC1->CR2 |= ADC_CR2_CAL;
    // 等待校准完成
    while (ADC1->CR2 & ADC_CR2_CAL)
    {}

    // 3. 启动转换
    // ADC1->CR2 |= ADC_CR2_SWSTART;
    ADC1->CR2 |= ADC_CR2_ADON;

    // 4. 等待转换完成
    while ((ADC1->SR & ADC_SR_EOC) == 0)
    {}
}

// 返回转换后的模拟电压值
double ADC1_ReadV(void)
{
    return ADC1->DR * 3.3 / 4095;
}

